﻿#include "NosepieceNikonLV232.h"
#include <QTextStream>
#include <QByteArray>
#include <QDebug>

NosepieceNikonLV232::NosepieceNikonLV232(QObject *parent)
    : QObject(parent),
      m_serialPort(nullptr),
      m_comPort("COM1"),
      m_baudRate(QSerialPort::Baud9600),
      m_dataBits(QSerialPort::Data8),
      m_parity(QSerialPort::NoParity),
      m_stopBits(QSerialPort::OneStop),
      m_lens(0)
{

    m_state = 0;

}

void NosepieceNikonLV232::state(char x)
{
    switch (m_state)
    {
    case 0:
        if(x == 'a')
        {
            m_state = 1;
        }
        break;
    case 1:
        if(x == 'R')
        {
            m_state = 2;
        }
        else
        {
            m_state = 0;
        }
        break;
    case 2:
        if(x == 'A')
        {
            m_state = 3;
        }
        else
        {
            m_state = 0;
        }
        break;
    case 3:
        if(x == 'R')
        {
            m_state = 4;
        }
        else
        {
            m_state = 0;
        }
        break;
    case 4:
        if( x > '0' && x < '6')
        {

            emit lensChanged(m_lens, x - '0' - 1);
            m_lens = x;
        }
        m_state = 0;
        break;
    default:
        m_state = 0;
        break;
    }
}

void NosepieceNikonLV232::dataArrived()
{
    QByteArray a  = m_serialPort->readAll();
    //qDebug() << a;
    for(int i = 0; i < a.size(); i++)
    {
        state(a.at(i));
    }
    //72 52 41 52 0D         rRAR.
    //61 52 41 52 33 0D      aRAR3
    //TODO 在这里发出 lensChanged 信号
    
}

void NosepieceNikonLV232::login()
{
    if(m_serialPort)
    {
        m_serialPort->close();
        delete m_serialPort;
    }
    m_serialPort = new QSerialPort(m_comPort, this);
    if(m_serialPort->open(QIODevice::ReadWrite))
    {
        qDebug() << "SerialPort Open ：" << m_comPort << "success";
        qDebug() << "baud rate = " << m_baudRate;
        qDebug() << "data bits = " << m_dataBits;
        qDebug() << "parity = " << m_parity;
        qDebug() << "stopBits = " <<  m_stopBits;

        m_serialPort->setBaudRate(m_baudRate);
        m_serialPort->setDataBits(static_cast<QSerialPort::DataBits> (m_dataBits));
        m_serialPort->setParity(static_cast<QSerialPort::Parity>(m_parity));
        m_serialPort->setStopBits(static_cast<QSerialPort::StopBits>(m_stopBits));
        m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
        m_serialPort->clearError();
        m_serialPort->clear();
        connect(m_serialPort, &QSerialPort::readyRead, this, &NosepieceNikonLV232::dataArrived);
        connect(&m_timer, &QTimer::timeout, this, &NosepieceNikonLV232::onTimer);
        m_timer.setInterval(1000);
        m_timer.start(1000);
    }
    else
    {
        qDebug() << "SerialPort open failed";
    }
}

void NosepieceNikonLV232::onTimer()
{
    cmd("rRAR\r");
}

void NosepieceNikonLV232::loadSettings(QSettings &settings)
{
    m_comPort = settings.value("Nosepiece/SerialPort", "COM1").toString();
    m_baudRate = settings.value("Nosepiece/BaudRate", QSerialPort::Baud9600).toInt();
    m_dataBits = settings.value("Nosepiece/DataBits", QSerialPort::Data8).toInt();
    m_parity = settings.value("Nosepiece/Parity", QSerialPort::NoParity).toInt();
    m_stopBits = settings.value("Nosepiece/StopBits", QSerialPort::OneStop).toInt();
}

void NosepieceNikonLV232::cmd(QString str)
{
    if(m_serialPort && m_serialPort->isWritable())
    {
        m_serialPort->write(str.toLocal8Bit());
        //QTextStream stream(m_serialPort);
        //qDebug() << "串口发送数据:" << (str);
    }
}

void NosepieceNikonLV232::setLens(int lens)
{
    lens++; // Olympus 的物镜转盘是从 1 开始计数的。所以这里要 + 1
    int lowerLimit = 1;
    int upperLimit = 5;
    lens = qBound(lowerLimit, lens, upperLimit);
    //cmd(QString("1OB %1\r\n").arg(lens));
    if(m_lens != lens)
    {
        m_lens = lens;
    }
}

void NosepieceNikonLV232::setLens(int oldLens, int newLens)
{
    setLens(newLens);
}

void NosepieceNikonLV232::forward()
{
    if(m_lens < 4)
    {
        setLens(m_lens + 1);
    }
    cmd("cRCW\r"); // NCNT2 应回复 oRCW\r    现在的代码没有判断回复的对不对
    //m_nosepiece->dynamicCall("Forward()");
}

void NosepieceNikonLV232::reverse()
{
    if(m_lens > 0)
    {
        setLens(m_lens - 1);
    }
    cmd("cRCC\r"); // NCNT2 应回复 oRCC\r    现在的代码没有判断回复的对不对
    //m_nosepiece->dynamicCall("Reverse()");
}
